package com.xunyin.modules.pay.rest;

import cn.hutool.core.util.StrUtil;
import com.github.pagehelper.util.StringUtil;
import com.github.wxpay.sdk.WXPayUtil;
import com.xunyin.api.ApiResult;
import com.xunyin.api.XunyinException;
import com.xunyin.common.bean.LocalUser;
import com.xunyin.common.interceptor.AuthCheck;
import com.xunyin.config.WXPayConfigImpl;
import com.xunyin.enums.*;
import com.xunyin.modules.couponnew.domain.MtCoupon;
import com.xunyin.modules.couponnew.param.MtCouponParam;
import com.xunyin.modules.couponnew.service.CouponService;
import com.xunyin.modules.log.AppLog;
import com.xunyin.modules.mtorder.domain.MtOrder;
import com.xunyin.modules.mtorder.service.MtOrderService;
import com.xunyin.modules.mtorder.service.dto.OrderDto;
import com.xunyin.modules.mtstore.service.StoreService;
import com.xunyin.modules.pay.PaymentService;
import com.xunyin.modules.user.domain.YxUser;
import com.xunyin.modules.user.service.YxUserService;
import com.xunyin.modules.user.service.dto.UserOrderDto;
import com.xunyin.modules.weixin.service.WeixinService;
import com.xunyin.utils.CommonUtilV;
import com.xunyin.utils.RedisUtils;
import com.xunyin.utils.ShopKeyUtils;
import com.xunyin.web.ResponseObject;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.math.BigDecimal;
import java.util.HashMap;
import java.util.Map;

/**
 * 支付类controller
 * <p>
 * Created by xunyinyunshang <3594419785@qq.com>
 * CopyRight 讯音云商 https://www.tonetn.com
 */
@Slf4j
@RestController
@Api(value = "支付接口相关", tags = "共享空间:支付接口相关")
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
public class ClientPayController {

    //private Logger logger = LoggerFactory.getLogger(this.getClass());

    /**
     * 微信服务接口
     */
    private final WeixinService weixinService;

    private final RedisUtils redisUtils;

    /**
     * 卡券服务接口
     */
    //@Autowired
    private final CouponService couponService;

    //private final TOrderServiceOld tOrderServiceOld;

    private final MtOrderService mtOrderService;

    private final YxUserService userService;

    private final StoreService storeService;


    /**
     * 支付服务接口
     * */
    private final PaymentService paymentService;

    /**
     * 去支付
     * */
/*    @RequestMapping(value = "/doPay", method = RequestMethod.GET)
    @CrossOrigin
    public ApiResult<Map<String,Object>> doPay(HttpServletRequest request) {
        try {
            Map<String, Object> result = paymentService.doPay(request);
            return ApiResult.ok(result);
            //return getSuccessResult(result);
        } catch (Exception e) {
            Map<String, Object> data = new HashMap();
            return ApiResult.fail(ErrorEnum.E_201.getErrorMsg(),data);
        }
    }*/


    /**
     * 请求支付
     * */
    @RequestMapping(value = "/pay/doPay", method = RequestMethod.GET)
    @CrossOrigin
    @AuthCheck
    public ApiResult<Map<String,Object>> doPay(HttpServletRequest request) {
        Long uid = LocalUser.getUser().getUid();
        YxUser user = userService.getById(uid.intValue());
        if (user == null) {
            throw new XunyinException("用户未登录");
        }
        try {
            Map<String, Object> result = paymentService.doPay(request,user);
            return ApiResult.ok(result);
            //return getSuccessResult(result);
        } catch (Exception e) {
            Map<String, Object> data = new HashMap();
            return ApiResult.fail(ErrorEnum.E_201.getErrorMsg(),data);
        }
    }


    /**
     * 用户卡券(小时卡、次数卡)购买支付
     */
    @AppLog(value = "用户卡券购买", type = 1)
    //@AuthCheck
    @PostMapping("/pay/userBuyConpon")
    @ApiOperation(value = "用户卡券购买", notes = "用户卡券购买")
    public ApiResult<Map<String, Object>> userBuyConpon(HttpServletRequest request, @RequestBody MtCouponParam param) {

        Integer storeId = param.getStoreId();
        Integer userId = param.getUserId();
        Integer couponId = param.getCouponId();
        String couponType = (param.getCouponType() == null) ? "H" : param.getCouponType();
        MtCoupon mtCoupon = couponService.getById(couponId);
        if (mtCoupon == null) {
            throw new XunyinException("找不到对应卡券");
        }
        // 卡券金额
        BigDecimal amount = mtCoupon.getAmount();

        OrderDto orderDto = new OrderDto();
        if (couponType.equals("H")) {
            orderDto.setType(OrderTypeEnum.HOUR.getKey());
        } else if (couponType.equals("N")) {
            orderDto.setType(OrderTypeEnum.NUMTIMES.getKey());
        }
        orderDto.setUserId(userId);
        orderDto.setStoreId(storeId);
        orderDto.setAmount(amount);
        orderDto.setUsePoint(0);
        String desc = "";
        if (mtCoupon.getType().equals(CouponTypeEnum.HOUR.getKey())) {
            desc = CouponTypeEnum.HOUR.getValue();
        } else if (mtCoupon.getType().equals(CouponTypeEnum.NUMTIMES.getKey())) {
            desc = CouponTypeEnum.NUMTIMES.getValue();
        }
        orderDto.setRemark("用户卡券购买" + desc);
        //orderDto.setParam(ruleParam);
        orderDto.setStatus(OrderStatusEnumV.CREATED.getKey());
        orderDto.setPayStatus(PayStatusEnum.WAIT.getKey());
        orderDto.setPointAmount(new BigDecimal("0"));
        orderDto.setOrderMode("");
        orderDto.setCouponId(couponId);

        MtOrder orderInfo = mtOrderService.saveOrder(orderDto);

        YxUser user = userService.getById(userId);
        String ip = CommonUtilV.getIPFromHttpRequest(request);
        BigDecimal pay = amount.multiply(new BigDecimal("100"));
        orderInfo.setPayType(PayTypeEnumV.JSAPI.getKey());
        ResponseObject paymentInfo = weixinService.createPrepayOrder(user, orderInfo, (pay.intValue()), "", 0, ip, PlatformTypeEnum.MP_WEIXIN.getCode());
        //ResponseObject paymentInfo = weixinService.createPrepayOrder(user, orderInfo, pay, "", 0, ip,PlatformTypeEnum.MP_WEIXIN.getCode());
        Map<String, Object> data = new HashMap();
        if (paymentInfo.getData() == null) {
            //return getFailureResult(201, "抱歉，发起支付失败");
            return ApiResult.fail(ErrorEnum.E_100029.getErrorMsg(), data);
        }

        Object payment = paymentInfo.getData();
        data.put("payment", payment);

        // 测试暂时用
        //UserOrderDto userOrderDto = mtOrderService.getOrderByOrderSn(orderInfo.getOrderSn());
        //boolean flag = weixinService.paymentCallback(userOrderDto);
/*        log.info("userOrderDto.getStoreId():"+userOrderDto.getStoreId());
        log.info("orderInfo.getStoreId():"+orderInfo.getStoreId());*/

        return ApiResult.ok(data);

    }


    /**
     * 支付回调
     */
    @RequestMapping(value = "/pay/weixinCallback", method = RequestMethod.POST)
    @CrossOrigin
    public void weixinCallback(HttpServletRequest request, HttpServletResponse response) throws Exception {
        log.info("微信支付结果回调....");
        Map<String, String> inParams = weixinService.processResXml(request);
        log.info("微信返回Map:" + inParams);
        if (!CollectionUtils.isEmpty(inParams)) {
            String orderSn = inParams.get("out_trade_no");// 商户订单号
            String orderId = inParams.get("transaction_id");// 微信订单号
            String tranAmt = inParams.get("total_fee");// 交易金额
            BigDecimal tranAmount = new BigDecimal(tranAmt).divide(new BigDecimal("100"), BigDecimal.ROUND_CEILING);
            // 参数校验
            if (StringUtil.isNotEmpty(orderSn) && StringUtil.isNotEmpty(tranAmt) && StringUtil.isNotEmpty(orderId)) {
                UserOrderDto orderInfo = mtOrderService.getOrderByOrderSn(orderSn);
                if (orderInfo != null) {
                    //MtStore storeInfo = orderInfo.getStoreInfo();
                    String callbackUrl = this.getApiUrl() + "/api/pay/weixinCallback";
                    WXPayConfigImpl wxPayConfig = WXPayConfigImpl.getInstance(callbackUrl, orderInfo.getStoreId(), redisUtils, storeService);
                    //WXPayConfigImpl wxPayConfig = WXPayConfigImpl.getInstance(env, storeInfo == null ? 0 : storeInfo.getId(), storeService);
                    boolean valid = WXPayUtil.isSignatureValid(inParams, wxPayConfig.getKey());
/*                    if (!valid) {
                        log.error("微信支付回调接口验签失败");
                        return;
                    }*/
                    // 订单金额
                    BigDecimal payAmount = orderInfo.getPayAmount();
                    int compareFlag = tranAmount.compareTo(payAmount);
                    if (true) { // compareFlag == 0，测试暂时去掉
                        if (orderInfo.getStatus().equals(OrderStatusEnumV.CREATED.getKey())) {
                            boolean flag = weixinService.paymentCallback(orderInfo);
                            log.info("回调结果：" + flag);
                            if (flag) {
                                weixinService.processRespXml(response, true);
                            } else {
                                weixinService.processRespXml(response, false);
                            }
                        } else {
                            log.error("订单{}已经支付，orderInfo.getStatus() = {}, CREATED.getKey() = {}", orderSn, orderInfo.getStatus(), OrderStatusEnumV.CREATED.getKey());
                        }
                    } else {
                        log.error("回调金额与支付金额不匹配 tranAmount = {}, payAmount = {}, compareFlag = {}", tranAmount, orderInfo.getPayAmount(), compareFlag);
                    }
                } else {
                    log.error("支付订单{}对应的信息不存在", orderSn);
                }
            }
        }
    }

    /**
     * 返回H5 url
     *
     * @return url
     */
    private String getApiUrl() {
        String apiUrl = redisUtils.getY(ShopKeyUtils.getApiUrl());
        if (StrUtil.isBlank(apiUrl)) {
            throw new XunyinException("请配置移动端api地址");
        }
        return apiUrl;
    }

}
